package client

import (
	"github.com/fsnotify/fsnotify"
	"github.com/spf13/viper"

	"fmt"
	"log"
	"os"
)

type YmlConf struct {
	DevEnv  EnvConfig `mapstructure:"dev"`
	TestEnv EnvConfig `mapstructure:"test"`
	PrdEnv  EnvConfig `mapstructure:"prd"`
}

type EnvConfig struct {
	MysqlConf `mapstructure:"mysql"`
	KafkaConf `mapstructure:"kafka"`
	RedisConf `mapstructure:"redis"`
}

type MysqlConf struct {
	UserName      string `mapstructure:"username"` //账号
	PassWord      string `mapstructure:"password"` //密码
	Host          string `mapstructure:"host"`     //数据库地址，可以是Ip或者域名
	Port          int16  `mapstructure:"port"`     //数据库端口
	Db            string `mapstructure:"db"`       //数据库名
	ConTimeOutSec string `mapstructure:"timeout"`  //连接超时，10秒
}

type KafkaConf struct {
	Dsn       []string `mapstructure:"dsn"` //kafka server 集群 ip:port
	Topic     string   `mapstructure:"topic"`
	Partition int32    `mapstructure:"partition"`
	Offset    int64    `mapstructure:"offset"`
}

type RedisConf struct {
	PassWord string `mapstructure:"password"` //密码
	Host     string `mapstructure:"host"`     //数据库地址，可以是Ip或者域名
	Port     int16  `mapstructure:"port"`     //数据库端口
	Db       int    `mapstructure:"db"`       //数据库名
	poolSize int    `mapstructure:"poolSize"` //连接池大小
}

var (
	// Config 整个配置文件内容
	Config = new(YmlConf)
	// EnvConf 当前某个环境的配置
	EnvConf = new(EnvConfig)
)

func initConfig() {
	viper.SetConfigFile("config.yml") // 指定配置文件路径 当前路径为项目的根路径
	err := viper.ReadInConfig()       // 读取配置信息
	if err != nil {                   // 读取配置信息失败
		panic(fmt.Errorf("Fatal error client file: %s \n", err))
	}
	// 将读取的配置信息保存至全局变量Conf
	if err := viper.Unmarshal(Config); err != nil {
		panic(fmt.Errorf("unmarshal conf failed, err:%s \n", err))
	}
	// 监控配置文件变化
	viper.WatchConfig()
	// 注意！！！配置文件发生变化后要同步到全局变量Conf
	viper.OnConfigChange(func(in fsnotify.Event) {
		log.Println("配置文件被人修改啦...")
		if err := viper.Unmarshal(Config); err != nil {
			panic(fmt.Errorf("unmarshal conf failed, err:%s \n", err))
		}
	})

	env := os.Getenv("env")
	log.Printf("env:[%v]\n", env)
	if env == "" {
		env = "dev"
	}
	// 将全局配置文件中 当前环境前缀的配置截取至 EvnConf
	sub := viper.Sub(env)
	if sub == nil {
		panic(fmt.Errorf("initConfig error client env:%v 配置不存在 \n", env))
	}
	uerr := sub.Unmarshal(EnvConf)
	if uerr != nil {
		panic(fmt.Errorf("initConfig Unmarshal envconfig error:%v\n", uerr))
	}
}
